package com.jcark.ui.utils;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.jcark.ui.R;
import com.jcark.ui.view.ViewState;
import com.jcark.ui.view.recyclerview.LinearItemDecoration;

/**
 * Description: 控件工具类<br>
 *
 * @author King.Zi<br>
 * @date 2022/06/14<br>
 * Email: 78688689@qq.com
 */
public class ViewUtils {
    private static long mLastClickTime = 0;
    private static final int sMaxColor = 255;

    private ViewUtils() {
    }

    /**
     * 获取透明度
     *
     * @param verticalOffset 垂直偏移量
     * @param viewHeight     控件高度
     * @param speed          移动速度(0.0~1f)
     */
    public static int getAlpha(int verticalOffset, int viewHeight, float speed) {
        if (verticalOffset > -viewHeight) {
            if (speed < 0) {
                speed = 0f;
            }
            if (speed > 1) {
                speed = 1f;
            }
            float percentage = (float) Math.abs(verticalOffset) / viewHeight;
            float alphaBg = (float) (sMaxColor - (sMaxColor * percentage * speed));
            if (alphaBg >= sMaxColor) {
                alphaBg = sMaxColor;
            } else if (alphaBg <= 0) {
                alphaBg = 0;
            }

            return (int) alphaBg;
        } else {
            return 0;
        }
    }

    /**
     * 获取不透明度
     *
     * @param verticalOffset 垂直偏移量
     * @param viewHeight     控件高度
     * @param speed          移动速度(0.0~1f)
     * @return
     */
    public static int getOpacity(int verticalOffset, int viewHeight, float speed) {
        if (verticalOffset > -viewHeight) {
            if (speed < 0) {
                speed = 0f;
            }
            float percentage = (float) Math.abs(verticalOffset) / viewHeight;
            float alphaView = 255 * percentage * speed;
            if (alphaView >= 255) {
                alphaView = 255;
            }

            return (int) alphaView;
        } else {
            return 255;
        }
    }

    /**
     * 为View设置圆角效果
     *
     * @param radius 圆角半径
     */
    public static void setRoundCorner(View target, float radius) {
        if (target == null) {
            return;
        }

        if (radius > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            target.setClipToOutline(true);
            target.setOutlineProvider(new RoundCornerProvider(radius));
        }
    }

    /**
     * 列表分隔线(默认为1dp)
     *
     * @param context
     * @param isShowLastLine 是否显示最后一条分隔线
     * @return 列表分隔线
     */
    public static RecyclerView.ItemDecoration getListDivider(@NonNull Context context, boolean isShowLastLine) {
        return getListDivider(context, 1f, R.color.list_line, isShowLastLine);
    }

    /**
     * 列表分隔线(分隔线颜色为默认值#F6F6F6)
     *
     * @param context        上下文
     * @param span           分隔线高度，单位dp
     * @param isShowLastLine 是否显示最后一条分隔线
     * @return 列表分隔线
     */
    public static RecyclerView.ItemDecoration getListDivider(@NonNull Context context, float span,
                                                             boolean isShowLastLine) {
        return getListDivider(context, span, R.color.list_line, isShowLastLine);
    }

    /**
     * 列表分隔线
     *
     * @param context        上下文
     * @param span           分隔线高度，单位dp
     * @param colorResId     颜色
     * @param isShowLastLine 是否显示最后一条分隔线
     * @return 列表分隔线
     */
    public static RecyclerView.ItemDecoration getListDivider(@NonNull Context context, float span,
                                                             @ColorRes int colorResId,
                                                             boolean isShowLastLine) {
        return new LinearItemDecoration.Builder(context)
                .setSpan(span)
                .setColorResource(colorResId)
                .setShowLastLine(isShowLastLine)
                .build();
    }

    /**
     * dp转px
     *
     * @param context
     * @param value
     * @return
     */
    public static int dpToPx(@NonNull Context context, float value) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (value * scale + 0.5f);
    }

    /**
     * 获取渐变的背景
     *
     * @param context      上下文
     * @param colors       颜色数组
     * @param orientation  渐变方向 {@link GradientDrawable.Orientation}
     * @param gradientType 类型,Shape {@link GradientDrawable GradientType}
     * @param shape        形状,包括RECTANT,OVAL,LINE,RING,参考{@link GradientDrawable Shape}
     * @param radius       圆角大小(dp)
     * @return
     */
    public static Drawable getBackgroundDrawable(@NonNull Context context, @ColorInt int[] colors,
                                                 GradientDrawable.Orientation orientation, int gradientType, int shape,
                                                 float radius) {
        GradientDrawable drawable = new GradientDrawable(orientation, colors);
        drawable.setGradientType(gradientType);
        drawable.setCornerRadius(dpToPx(context, radius));
        drawable.setShape(shape);
        return drawable;
    }

    /**
     * 获取渐变的背景(矩形-线性渐变)
     *
     * @param context     上下文
     * @param colors      颜色数组
     * @param orientation 渐变方向 {@link GradientDrawable.Orientation}
     * @param radius      圆角大小(dp)
     * @return
     */
    public static Drawable getBackgroundDrawable(@NonNull Context context, @ColorInt int[] colors,
                                                 GradientDrawable.Orientation orientation, float radius) {
        return getBackgroundDrawable(context, colors, orientation, GradientDrawable.LINEAR_GRADIENT,
                GradientDrawable.RECTANGLE, radius);
    }

    /**
     * 获取背景
     *
     * @param context 上下文
     * @param color   颜色
     * @param radius  圆角大小(dp)
     * @return
     */
    public static Drawable getBackgroundDrawable(@NonNull Context context, @ColorInt int color, float radius) {
        GradientDrawable drawable = new GradientDrawable();
        drawable.setColor(color);
        drawable.setCornerRadius(dpToPx(context, radius));
        drawable.setShape(GradientDrawable.RECTANGLE);
        return drawable;
    }

    /**
     * 获取背景
     *
     * @param context 上下文
     * @param color   颜色
     * @param radii   圆角数组
     * @return
     */
    public static Drawable getBackgroundDrawable(Context context, @ColorInt int color, float[] radii) {
        GradientDrawable drawable = new GradientDrawable();
        drawable.setColor(color);
        drawable.setCornerRadii(radii);
        drawable.setShape(GradientDrawable.RECTANGLE);
        return drawable;
    }

    /**
     * 获取边框背景
     *
     * @param context     上下文
     * @param strokeColor 边框颜色
     * @param strokeWidth 边框大小
     * @param share       形状,包括RECTANT,OVAL,LINE,RING,参考{@link GradientDrawable Shape}
     * @param radius      圆角大小(dp)
     * @return
     */
    public static Drawable getBackgroundStrokeDrawable(@NonNull Context context, @ColorInt int strokeColor,
                                                       int strokeWidth,
                                                       int share,
                                                       float radius) {
        GradientDrawable drawable = new GradientDrawable();
        drawable.setStroke(dpToPx(context, strokeWidth), strokeColor);
        drawable.setCornerRadius(dpToPx(context, radius));
        drawable.setShape(share);
        return drawable;
    }

    /**
     * 获取边框背景
     *
     * @param context     上下文
     * @param strokeColor 边框颜色
     * @param radius      圆角大小(dp)
     * @return
     */
    public static Drawable getBackgroundStrokeDrawable(@NonNull Context context, @ColorInt int strokeColor,
                                                       float radius) {
        return getBackgroundStrokeDrawable(context, strokeColor, 1, GradientDrawable.RECTANGLE, radius);
    }

    /**
     * 判断是否为快速点击
     *
     * @param delayTime 延迟时间(单位毫秒)
     * @return
     */
    public static boolean isFastClick(int delayTime) {
        long time = System.currentTimeMillis();
        if (time - mLastClickTime < delayTime) {
            return true;
        }
        mLastClickTime = time;
        return false;
    }

    /**
     * 判断是否为快速点击(每次点击后都会更新最后的点击时间，强制间隔指定时间)
     *
     * @param delayTime 延迟时间(单位毫秒)
     * @return
     */
    public static boolean isFastClickWithForceDelay(int delayTime) {
        long time = System.currentTimeMillis();
        if (time - mLastClickTime < delayTime) {
            mLastClickTime = time;
            return true;
        }
        return false;
    }

    /**
     * 设置控件的可见性
     *
     * @param view       控件
     * @param visibility 显性属性值
     */
    public static void setVisibility(ViewGroup view, int visibility) {
        if (null != view) {
            for (int i = 0; i < view.getChildCount(); i++) {
                setVisibility(view.getChildAt(i), visibility);
            }
        }
    }

    /**
     * 设置view的可显性属性
     *
     * @param view       view
     * @param visibility 显性属性值
     */
    public static void setVisibility(View view, int visibility) {
        if (visibility != view.getVisibility()) {
            view.setVisibility(visibility);
        }
    }

    /**
     * 设置滤色器，可实现让指定布局置灰
     *
     * @param view       布局或控件
     * @param saturation 饱和度
     */
    public static void setColorFilter(View view, float saturation) {
        ColorMatrix matrix = new ColorMatrix();
        matrix.setSaturation(0);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
    }

    /**
     * 设置列表项中的view状态
     */
    public static void setViewState(ViewState viewState, View... views) {
        if (null != views && views.length > 0) {
            for (int index = 0; index < views.length; index++) {
                switch (viewState) {
                    case NORMAL:
                        views[index].setEnabled(true);
                        views[index].setClickable(false);
                        views[index].setSelected(false);
                        break;
                    case DISABLE:
                        views[index].setEnabled(false);
                        views[index].setClickable(true);
                        views[index].setSelected(false);
                        break;
                    case SELECTED:
                        views[index].setEnabled(true);
                        views[index].setClickable(false);
                        views[index].setSelected(true);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * Value of dp to value of px.
     *
     * @param dpValue The value of dp.
     * @return value of px
     */
    public static int dp2px(final float dpValue) {
        final float scale = Resources.getSystem().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * Value of px to value of dp.
     *
     * @param pxValue The value of px.
     * @return value of dp
     */
    public static int px2dp(final float pxValue) {
        final float scale = Resources.getSystem().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * Value of sp to value of px.
     *
     * @param spValue The value of sp.
     * @return value of px
     */
    public static int sp2px(final float spValue) {
        final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    /**
     * Value of px to value of sp.
     *
     * @param pxValue The value of px.
     * @return value of sp
     */
    public static int px2sp(final float pxValue) {
        final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    public static int getNavBarHeight(@NonNull Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId != 0) {
            return res.getDimensionPixelSize(resourceId);
        } else {
            return 0;
        }
    }

    /**
     * Return the status bar's height.
     *
     * @return the status bar's height
     */
    public static int getStatusBarHeight(@NonNull Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        return resources.getDimensionPixelSize(resourceId);
    }
}
